<template>
  <div class="table-box">
    <ProTable
      ref="proTable"
      title="用户列表"
      highlight-current-row
      :columns="columns"
      :request-api="getUserList"
      :row-class-name="tableRowClassName"
      :span-method="objectSpanMethod"
      :show-summary="true"
      :summary-method="getSummaries"
      @row-click="rowClick"
    >
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <el-button type="primary" :icon="CirclePlus" @click="proTable?.element?.toggleAllSelection">
          全选 / 全不选
        </el-button>
        <el-button type="primary" :icon="Pointer" plain @click="setCurrent"> 选中第五行 </el-button>
        <el-button
          type="danger"
          :icon="Delete"
          plain
          :disabled="!scope.isSelected"
          @click="batchDelete(scope.selectedListIds)"
        >
          批量删除用户
        </el-button>
      </template>
      <!-- Expand -->
      <template #expand="scope">
        {{ scope.row }}
      </template>
      <!-- 表格操作 -->
      <template #operation="scope">
        <el-button type="primary" link :icon="Refresh" @click="resetPass(scope.row)"> 重置密码 </el-button>
        <el-button type="primary" link :icon="Delete" @click="deleteAccount(scope.row)"> 删除 </el-button>
      </template>
      <template #append>
        <span style="color: var(--el-color-primary)">
          我是插入在表格最后的内容。若表格有合计行，该内容会位于合计行之上。
        </span>
      </template>
    </ProTable>
  </div>
</template>

<script setup lang="tsx" name="complexProTable">
  import { ref } from "vue"
  import { ElMessage } from "element-plus"
  import { User } from "@/api/interface"
  import { useHandleData } from "@/hooks/useHandleData"
  import ProTable from "@/components/ProTable/index.vue"
  import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults"
  import { ProTableInstance, ColumnProps, HeaderRenderScope } from "@/components/ProTable/interface"
  import { CirclePlus, Pointer, Delete, Refresh } from "@element-plus/icons-vue"
  import { getUserList, deleteUser, resetUserPassWord, getUserStatus, getUserGender } from "@/api/modules/user"

  // 获取 ProTable DOM
  const proTable = ref<ProTableInstance>()

  // 自定义渲染表头（使用tsx语法）
  const headerRender = (scope: HeaderRenderScope<User.ResUserList>) => {
    return (
      <el-button type="primary" onClick={() => ElMessage.success("我是通过 tsx 语法渲染的表头")}>
        {scope.column.label}
      </el-button>
    )
  }

  // 表格配置项
  const columns: ColumnProps<User.ResUserList>[] = [
    { type: "selection", width: 80 },
    { type: "index", label: "#", width: 80 },
    { type: "expand", label: "Expand", width: 100 },
    {
      prop: "base",
      label: "基本信息",
      headerRender,
      _children: [
        { prop: "username", label: "用户姓名", width: 110 },
        { prop: "user.detail.age", label: "年龄", width: 100 },
        {
          prop: "gender",
          label: "性别",
          width: 100,
          enum: getUserGender,
          fieldNames: { label: "genderLabel", value: "genderValue" }
        },
        {
          prop: "details",
          label: "详细资料",
          _children: [
            { prop: "idCard", label: "身份证号" },
            { prop: "email", label: "邮箱" },
            { prop: "address", label: "居住地址" }
          ]
        }
      ]
    },
    {
      prop: "status",
      label: "用户状态",
      tag: true,
      enum: getUserStatus,
      fieldNames: { label: "userLabel", value: "userStatus" }
    },
    { prop: "createTime", label: "创建时间", width: 200 },
    { prop: "operation", label: "操作", fixed: "right", width: 230 }
  ]

  // 选择行
  const setCurrent = () => {
    proTable.value?.element?.setCurrentRow(proTable.value?.tableData[4])
  }

  // 表尾合计行（自行根据条件计算）
  interface SummaryMethodProps<T = User.ResUserList> {
    columns: TableColumnCtx<T>[]
    data: T[]
  }
  const getSummaries = (param: SummaryMethodProps) => {
    const { columns } = param
    const sums: string[] = []
    columns.forEach((column, index) => {
      if (index === 0) return (sums[index] = "合计")
      else sums[index] = "N/A"
    })
    return sums
  }

  // 列合并
  interface SpanMethodProps {
    row: User.ResUserList
    column: TableColumnCtx<User.ResUserList>
    rowIndex: number
    columnIndex: number
  }
  const objectSpanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
    if (columnIndex === 3) {
      if (rowIndex % 2 === 0) return { rowspan: 2, colspan: 1 }
      else return { rowspan: 0, colspan: 0 }
    }
  }

  // 设置列样式
  const tableRowClassName = ({ rowIndex }: { row: User.ResUserList; rowIndex: number }) => {
    if (rowIndex === 2) return "warning-row"
    if (rowIndex === 6) return "success-row"
    return ""
  }

  // 单击行
  const rowClick = (row: User.ResUserList, column: TableColumnCtx<User.ResUserList>) => {
    if (column.property == "radio" || column.property == "operation") return
    console.log(row)
    ElMessage.success("当前行被点击了！")
  }

  // 删除用户信息
  const deleteAccount = async (params: User.ResUserList) => {
    await useHandleData(deleteUser, { id: [params.id] }, `删除【${params.username}】用户`)
    proTable.value?.getTableList()
  }

  // 批量删除用户信息
  const batchDelete = async (id: string[]) => {
    await useHandleData(deleteUser, { id }, "删除所选用户信息")
    proTable.value?.clearSelection()
    proTable.value?.getTableList()
  }

  // 重置用户密码
  const resetPass = async (params: User.ResUserList) => {
    await useHandleData(resetUserPassWord, { id: params.id }, `重置【${params.username}】用户密码`)
    proTable.value?.getTableList()
  }
</script>

<style lang="scss">
  .el-table .warning-row,
  .el-table .warning-row .el-table-fixed-column--right,
  .el-table .warning-row .el-table-fixed-column--left {
    background-color: var(--el-color-warning-light-9);
  }
  .el-table .success-row,
  .el-table .success-row .el-table-fixed-column--right,
  .el-table .success-row .el-table-fixed-column--left {
    background-color: var(--el-color-success-light-9);
  }
</style>
